package org.jing.core.lang.data;

import org.jing.core.util.GenericUtil;

import java.util.Collection;
import java.util.HashMap;
import java.util.function.BiConsumer;

/**
 * Description: 计数器 <br>
 *
 * @author bks <br>
 * @since 2024-07-23 <br>
 */
@SuppressWarnings({ "unused", "unchecked" })
public final class CountMap<T> {
    private final HashMap<T, Integer> map = new HashMap<>();

    /**
     * Description: 新建一个空的计数器. <br>
     */
    public CountMap() {}

    /**
     * Description: 新建一个计数器. <br>
     * 为集合中的每个元素进行一次计数. <br>
     *
     * @param collection 集合 <br>
     */
    public CountMap(Collection<T> collection) {
        GenericUtil.loop(collection, this::add);
    }

    /**
     * Description: 新建一个计数器. <br>
     * 为数组中的每个元素进行一次计数. <br>
     *
     * @param keys 数组 <br>
     */
    public CountMap(T... keys) {
        GenericUtil.loop(keys, this::add);
    }

    /**
     * Description: 为元素进行一次计数增加. <br>
     *
     * @param key <br>
     */
    public void add(T key) {
        Integer count = map.getOrDefault(key, 0);
        map.put(key, count + 1);
    }

    /**
     * Description: 为元素进行一次计数减少. <br>
     *
     * @param key <br>
     */
    public void reduce(T key) {
        Integer count = map.getOrDefault(key, 0);
        map.put(key, count - 1);
    }

    /**
     * Description: 获取元素当前计数. <br>
     *
     * @param key <br>
     */
    public int get(T key) {
        return map.getOrDefault(key, 0);
    }

    /**
     * Description: 删除元素计数. <br>
     *
     * @param key <br>
     */
    public int remove(T key) {
        Integer integer = map.remove(key);
        return null == integer ? 0 : integer;
    }

    /**
     * Description: 清空所有计数. <br>
     */
    public void clear() {
        map.clear();
    }

    /**
     * Description: 遍历元素计数. <br>
     *
     * @param action <br>
     */
    public void forEach(BiConsumer<T, Integer> action) {
        map.forEach(action);
    }
}
